package wechat

import (
	"encoding/xml"
	"fmt"
	"os"
	"time"
	"wechat/src/tools"
)

type JsLogin struct {
	Appid       string `json:"appid"`
	RedirectUri string `json:"redirect_uri"`
	Func        string `json:"fun"`
	Lang        string `json:"lang"`
	TimeStamp   int    `json:"_"`
}

func JsLoginNewConfig() *JsLogin {
	return &JsLogin{
		Appid:       "wx782c26e4c19acffb",
		RedirectUri: "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage",
		Func:        "new",
		Lang:        "zh_CN",
		TimeStamp:   int(time.Now().Unix()),
	}
}

type MmwebwxLogin struct {
	LoginIcon bool   `json:"loginicon"`
	Uuid      string `json:"uuid"`
	Tip       int    `json:"tip"`
	R         int    `json:"r"`
	TimeStamp int    `json:"_"`
}

func MmwebwxLoginNewConfig(uuid string) MmwebwxLogin {
	var timestamp int64 = time.Now().UnixMilli() //获取13位的时间戳
	return MmwebwxLogin{
		LoginIcon: true,
		Uuid:      uuid,
		Tip:       1,
		R:         int(^(int32)(timestamp)),
		TimeStamp: int(timestamp),
	}
}

type BaseRequest struct {
	DeviceID string `json:"DeviceID"`
	Sid      string `json:"Sid"`
	Skey     string `json:"Skey"`
	Uin      string `json:"Uin"`
}

type Webwxinit struct {
	Get WebwxinitGet

	Post WebwxinitPost
}

type WebwxinitGet struct {
	R          string `json:"r"`
	PassTicket string `json:"pass_ticket"`
}

type WebwxinitPost struct {
	BaseRequest BaseRequest `json:"BaseRequest"`
}

func WebwxinitNewConfig(webwxnewLoginPage *WebwxnewLoginPage) *Webwxinit {
	var timestamp int64 = time.Now().UnixMilli()
	return &Webwxinit{
		Get: WebwxinitGet{R: fmt.Sprintf("%d", ^(int32)(timestamp)), PassTicket: webwxnewLoginPage.PassTicket},

		Post: WebwxinitPost{BaseRequest: BaseRequest{
			DeviceID: "e" + tools.StringRandom(10, 15),
			Sid:      webwxnewLoginPage.WxSid,
			Skey:     webwxnewLoginPage.SKey,
			Uin:      webwxnewLoginPage.WxUin,
		}},
	}
}

type Webwxstatusnotify struct {
	WebwxstatusnotifyGet WebwxstatusnotifyGet `json:"webwxstatusnotify_get"`

	WebwxstatusnotifyPost WebwxstatusnotifyPost `json:"webwxstatusnotify_post"`
}

//lang: zh_CN
//pass_ticket: E2zLcGQoiAfgCNzWXslr3%252BNn9v1GLgORoQg1M7Nl6ahzliwnRifz3oxFn99GRLjNsisrcowTE7Ec%252FRnxu6%252Bo5Q%253D%253D

type WebwxstatusnotifyGet struct {
	Lang       string `json:"lang"`
	PassTicket string `json:"pass_ticket"`
}

type WebwxstatusnotifyPost struct {
	BaseRequest  BaseRequest `json:"BaseRequest"`
	ClientMsgId  int         `json:"ClientMsgId"`
	Code         int         `json:"Code"`
	FromUserName string      `json:"FromUserName"`
	ToUserName   string      `json:"ToUserName"`
}

func WebwxstatusnotifyNewConfig(webwxnewLoginPage *WebwxnewLoginPage, user *User) *Webwxstatusnotify {
	var timestamp int64 = time.Now().UnixMilli()
	return &Webwxstatusnotify{
		WebwxstatusnotifyGet: WebwxstatusnotifyGet{
			Lang:       "zh_CN",
			PassTicket: webwxnewLoginPage.PassTicket,
		},
		WebwxstatusnotifyPost: WebwxstatusnotifyPost{
			BaseRequest: BaseRequest{
				DeviceID: "e" + tools.StringRandom(10, 15),
				Sid:      webwxnewLoginPage.WxSid,
				Skey:     webwxnewLoginPage.SKey,
				Uin:      webwxnewLoginPage.WxUin,
			},
			ClientMsgId:  int(timestamp),
			Code:         3,
			FromUserName: user.UserName,
			ToUserName:   user.UserName,
		},
	}
}

type Synccheck struct {
	TimeStamp int    `json:"_"`
	Synckey   string `json:"synckey"`
	Deviceid  string `json:"deviceid"`
	Uin       string `json:"uin"`
	Sid       string `json:"sid"`
	Skey      string `json:"skey"`
	R         int    `json:"r"`
}

func SynccheckNewConfig(webwxnewLoginPage *WebwxnewLoginPage, syncKeys *SyncKeysJsonData, startTime int64) *Synccheck {
	var timestamp int64 = time.Now().UnixMilli()
	return &Synccheck{
		R:         int(timestamp),
		Skey:      webwxnewLoginPage.SKey,
		Sid:       webwxnewLoginPage.WxSid,
		Uin:       webwxnewLoginPage.WxUin,
		Deviceid:  "e" + tools.StringRandom(10, 15),
		Synckey:   syncKeys.ToString(),
		TimeStamp: int(startTime),
	}
}

type Webwxsync struct {
	Get  WebwxsyncGet
	Post WebwxsyncPost
}

type WebwxsyncGet struct {
	Sid        string `json:"sid"`
	Skey       string `json:"skey"`
	Lang       string `json:"lang"`
	PassTicket string `json:"pass_ticket"`
}

type WebwxsyncPost struct {
	BaseRequest BaseRequest      `json:"BaseRequest"`
	SyncKey     SyncKeysJsonData `json:"SyncKey"`
	RR          int              `json:"rr"`
}

func WebwxsyncNewConfig(webwxnewLoginPage *WebwxnewLoginPage, syncKeys SyncKeysJsonData) *Webwxsync {
	timestamp := time.Now().UnixMilli()
	return &Webwxsync{
		Get: WebwxsyncGet{
			Sid:        webwxnewLoginPage.WxSid,
			Skey:       webwxnewLoginPage.SKey,
			Lang:       "zh_CN",
			PassTicket: webwxnewLoginPage.PassTicket,
		},
		Post: WebwxsyncPost{
			BaseRequest: BaseRequest{
				DeviceID: "e" + tools.StringRandom(10, 15),
				Sid:      webwxnewLoginPage.WxSid,
				Skey:     webwxnewLoginPage.SKey,
				Uin:      webwxnewLoginPage.WxUin,
			},
			SyncKey: syncKeys,
			RR:      int(^int32(timestamp)),
		},
	}
}

type Webwxgetcontact struct {
	R    int    `json:"r"`
	Seq  int    `json:"seq"`
	Skey string `json:"skey"`
}

func WebwxgetcontactNewConfig(webwxnewLoginPage *WebwxnewLoginPage) *Webwxgetcontact {
	var timestamp int64 = time.Now().UnixMilli()
	return &Webwxgetcontact{
		R:    int(timestamp),
		Seq:  0,
		Skey: webwxnewLoginPage.SKey,
	}
}

type Webwxuploadmedia struct {
	Get  WebwxuploadmediaGet
	Post WebwxuploadmediaPost
}

type WebwxuploadmediaGet struct {
	F string `json:"f"`
}

type WebwxuploadmediaPost struct {
	Id                 string             `json:"id"`
	Name               string             `json:"name"`
	LastModifiedDate   time.Time          `json:"lastModifiedDate"`
	Type               string             `json:"type"`
	Size               int                `json:"size"`
	Mediatype          string             `json:"mediatype"`
	Uploadmediarequest Uploadmediarequest `json:"uploadmediarequest"`
	WebwxDataTicket    string             `json:"webwx_data_ticket"`
	PassTicket         string             `json:"pass_ticket"`
	//Filename           *os.File            `json:"filename"`
}

type Uploadmediarequest struct {
	UploadType    int         `json:"UploadType"`
	BaseRequest   BaseRequest `json:"BaseRequest"`
	ClientMediaId int         `json:"ClientMediaId"`
	TotalLen      int         `json:"TotalLen"`
	StartPos      int         `json:"StartPos"`
	DataLen       int         `json:"DataLen"`
	MediaType     int         `json:"MediaType"`
	FromUserName  string      `json:"FromUserName"`
	ToUserName    string      `json:"ToUserName"`
	FileMd5       string      `json:"FileMd5"`
}

// id: WU_FILE_0
// name: th.jpg
// type: image/jpeg
// lastModifiedDate: Fri May 03 2024 17:52:36 GMT+0800 (中国标准时间)
// size: 9499
// mediatype: pic
// uploadmediarequest: {"UploadType":2,"BaseRequest":{"Uin":1584483238,"Sid":"xqwB0Flahmt/qTaG","Skey":"@crypt_1dbbc087_3cb343a885f6731134f67446dfb79360","DeviceID":"e854197638409471"},"ClientMediaId":1714735528479,"TotalLen":9499,"StartPos":0,"DataLen":9499,"MediaType":4,"FromUserName":"@4fad24fc0449ff8c5a709c6a996ac71e2139a2bfe6c7e00edf3b7e4ce25611da","ToUserName":"@d4aafa8c2cd07651b4bcdeab9323d42a338e43e72d3613d953c04f423cd60e92","FileMd5":"6e6f33119f651e3ae492c14c7e3d758f"}
// webwx_data_ticket: gScYpuZcyO7RlNEcRp5biO3h
// pass_ticket: undefined
// filename: (二进制)
func WebwxuploadmediaNewConfig(webwxnewLoginPage *WebwxnewLoginPage, user MsgUser, cookies map[string]string, file os.FileInfo, mimeType string, fileMd5 string, mediatype string) *Webwxuploadmedia {

	timestamp := time.Now().UnixMilli()
	passTicket := ""
	switch mediatype {
	case "pic":
		passTicket = "undefined"
	case "doc":
		passTicket = webwxnewLoginPage.PassTicket
	}

	return &Webwxuploadmedia{
		Get: WebwxuploadmediaGet{F: "json"},
		Post: WebwxuploadmediaPost{
			Id:               "WU_FILE_0",
			Name:             file.Name(),
			LastModifiedDate: file.ModTime(),
			Type:             mimeType,
			Size:             int(file.Size()),
			Mediatype:        mediatype, //pic 图片 和 doc 文件
			Uploadmediarequest: Uploadmediarequest{
				UploadType: 2,
				BaseRequest: BaseRequest{
					DeviceID: "e" + tools.StringRandom(10, 15),
					Sid:      webwxnewLoginPage.WxSid,
					Skey:     webwxnewLoginPage.SKey,
					Uin:      webwxnewLoginPage.WxUin,
				},
				ClientMediaId: int(timestamp),
				TotalLen:      int(file.Size()),
				StartPos:      0,
				DataLen:       int(file.Size()),
				MediaType:     4,
				FromUserName:  user.FromUserName,
				ToUserName:    user.ToUserName,
				FileMd5:       fileMd5,
			},
			WebwxDataTicket: cookies["webwx_data_ticket"],
			PassTicket:      passTicket, //webwxnewLoginPage.PassTicket
			//Filename:        file.Data,
		},
	}
}

// 发送消息接收者和发送者
type MsgUser struct {
	FromUserName string `json:"FromUserName"`
	ToUserName   string `json:"ToUserName"`
}

type Webwxsendmsg struct {
	Get  WebwxsendmsgGet
	Post WebwxsendmsgPost
}

type WebwxsendmsgGet struct {
	Lang       string `json:"lang"`
	PassTicket string `json:"pass_ticket"`
}

type WebwxsendmsgPost struct {
	BaseRequest BaseRequest         `json:"BaseRequest"`
	Msg         WebwxsendmsgPostMsg `json:"Msg"`
	Scene       int                 `json:"Scene"`
}

type WebwxsendmsgPostMsg struct {
	Type         int    `json:"Type"`
	ClientMsgId  int    `json:"ClientMsgId"`
	Content      string `json:"Content"`
	FromUserName string `json:"FromUserName"`
	LocalID      int    `json:"LocalId"`
	ToUserName   string `json:"ToUserName"`
}

func WebwxsendmsgNewConfig(webwxnewLoginPage *WebwxnewLoginPage, msg MsgUser, content string) *Webwxsendmsg {
	timestamp := time.Now().UnixMicro() * 10
	return &Webwxsendmsg{
		Get: WebwxsendmsgGet{
			Lang:       "zh_CN",
			PassTicket: webwxnewLoginPage.PassTicket,
		},
		Post: WebwxsendmsgPost{
			BaseRequest: BaseRequest{
				DeviceID: "e" + tools.StringRandom(10, 15),
				Sid:      webwxnewLoginPage.WxSid,
				Skey:     webwxnewLoginPage.SKey,
				Uin:      webwxnewLoginPage.WxUin,
			},
			Msg: WebwxsendmsgPostMsg{
				Type:         1,
				ClientMsgId:  int(timestamp),
				Content:      content,
				FromUserName: msg.FromUserName,
				LocalID:      int(timestamp),
				ToUserName:   msg.ToUserName,
			},
			Scene: 0,
		},
	}
}

type Webwxsendmsgimg struct {
	Get  WebwxsendmsgimgGet
	Post WebwxsendmsgimgPost
}

type WebwxsendmsgimgGet struct {
	Fun  string `json:"fun"`
	F    string `json:"f"`
	Lang string `json:"lang"`
}

type WebwxsendmsgimgPost struct {
	BaseRequest BaseRequest            `json:"BaseRequest"`
	Msg         WebwxsendmsgimgPostMsg `json:"Msg"`
	Scene       int                    `json:"Scene"`
}

type WebwxsendmsgimgPostMsg struct {
	Type         int    `json:"Type"`
	ClientMsgId  int    `json:"ClientMsgId"`
	Content      string `json:"Content"`
	FromUserName string `json:"FromUserName"`
	LocalID      int    `json:"LocalId"`
	MediaId      string `json:"MediaId"`
	ToUserName   string `json:"ToUserName"`
}

func WebwxsendmsgimgNewConfig(webwxnewLoginPage *WebwxnewLoginPage, msg MsgUser, mediaId string) *Webwxsendmsgimg {
	timestamp := time.Now().UnixMicro() * 10
	return &Webwxsendmsgimg{
		Get: WebwxsendmsgimgGet{
			Lang: "zh_CN",
			F:    "json",
			Fun:  "async",
		},
		Post: WebwxsendmsgimgPost{
			BaseRequest: BaseRequest{
				DeviceID: "e" + tools.StringRandom(10, 15),
				Sid:      webwxnewLoginPage.WxSid,
				Skey:     webwxnewLoginPage.SKey,
				Uin:      webwxnewLoginPage.WxUin,
			},
			Msg: WebwxsendmsgimgPostMsg{
				Type:         3,
				ClientMsgId:  int(timestamp),
				Content:      "",
				FromUserName: msg.FromUserName,
				LocalID:      int(timestamp),
				MediaId:      mediaId,
				ToUserName:   msg.ToUserName,
			},
			Scene: 0,
		},
	}
}

type Webwxsendappmsg struct {
	Get  WebwxsendappmsgGet
	Post WebwxsendappmsgPost
}

// fun: async
// f: json
// lang: zh_CN
// pass_ticket: at%252BGGccEUoQ6rIcYwl7kb9CapsZe8nmZC2yh7OmYDztS5z9DkhDHsd50HBajymNmUcBYCZNAAPoxEq%252FRGfLXPg%253D%253D
type WebwxsendappmsgGet struct {
	//fun: async #固定值
	//f: json #固定值
	//mod: desktop #固定值
	Func       string `json:"func"`
	F          string `json:"f"`
	Mod        string `json:"mod"`
	PassTicket string `json:"pass_ticket"`
}

type WebwxsendappmsgPost struct {
	BaseRequest BaseRequest            `json:"BaseRequest"`
	Msg         WebwxsendappmsgPostMsg `json:"Msg"`
	Scene       int                    `json:"Scene"`
}

// ClientMsgId
type WebwxsendappmsgPostMsg struct {
	ClientMsgId  int    `json:"ClientMsgId"`
	Content      string `json:"Content"`
	FromUserName string `json:"FromUserName"`
	LocalID      int    `json:"LocalId"`
	ToUserName   string `json:"ToUserName"`
	Type         int    `json:"Type"`
}

func WebwxsendappmsgNewConfig(webwxnewLoginPage *WebwxnewLoginPage, msg MsgUser, content string) *Webwxsendappmsg {

	timestamp := time.Now().UnixMicro() * 10
	return &Webwxsendappmsg{
		Get: WebwxsendappmsgGet{
			Func:       "async",
			F:          "json",
			Mod:        "zh_CN",
			PassTicket: webwxnewLoginPage.PassTicket,
		},
		Post: WebwxsendappmsgPost{
			BaseRequest: BaseRequest{
				DeviceID: "e" + tools.StringRandom(10, 15),
				Sid:      webwxnewLoginPage.WxSid,
				Skey:     webwxnewLoginPage.SKey,
				Uin:      webwxnewLoginPage.WxUin,
			},
			Msg: WebwxsendappmsgPostMsg{
				ClientMsgId:  int(timestamp),
				Content:      content,
				FromUserName: msg.FromUserName,
				LocalID:      int(timestamp),
				ToUserName:   msg.ToUserName,
				Type:         6,
			},
			Scene: 0,
		},
	}
}

type WebwxsendappmsgAppmsg struct {
	XMLName   xml.Name                  `xml:"appmsg"`
	AppID     string                    `xml:"appid,attr"`
	SDKVer    string                    `xml:"sdkver,attr"`
	Title     string                    `xml:"title"`
	Des       string                    `xml:"des"`
	Action    string                    `xml:"action"`
	Type      int                       `xml:"type"`
	Content   string                    `xml:"content"`
	Url       string                    `xml:"url"`
	Lowurl    string                    `xml:"lowurl"`
	AppAttach *WebwxsendappmsgAppAttach `xml:"appattach"`
	Extinfo   string                    `xml:"extinfo"`
}

type WebwxsendappmsgAppAttach struct {
	TotalLen int    `xml:"totallen"`
	AttachID string `xml:"attachid"`
	FileExt  string `xml:"fileext"`
}

func WebwxsendappmsgAppmsgNewConfig(title string, mediaId string, fileType string) *WebwxsendappmsgAppmsg {
	return &WebwxsendappmsgAppmsg{
		AppID:   "wxeb7ec651dd0aefa9",
		SDKVer:  "",
		Title:   title,
		Des:     "",
		Action:  "",
		Type:    6,
		Content: "",
		Url:     "",
		Lowurl:  "",
		AppAttach: &WebwxsendappmsgAppAttach{
			TotalLen: 6,
			AttachID: mediaId,
			FileExt:  fileType,
		},
		Extinfo: "",
	}
}

type Webwxgetmsgimg struct {
	MsgID string `json:"MsgID"`
	Skey  string `json:"skey"`
	//Type  string `json:"type"`//设置以后就是获取缩略图-不设置就是原图
}

func WebwxgetmsgimgNewConfig(webwxnewLoginPage *WebwxnewLoginPage, msgId string) *Webwxgetmsgimg {
	return &Webwxgetmsgimg{
		MsgID: msgId,
		Skey:  webwxnewLoginPage.SKey,
		//Type:  "slave",
	}
}

type Webwxgeticon struct {
	Seq      int    `json:"seq"`
	Username string `json:"username"`
	Skey     string `json:"skey"`
}

func WebwxgeticonNewConfig(webwxnewLoginPage *WebwxnewLoginPage, username string) *Webwxgeticon {
	timestamp := time.Now().UnixMicro()
	return &Webwxgeticon{
		Seq:      int(int32(timestamp)),
		Username: username,
		Skey:     webwxnewLoginPage.SKey,
	}
}

type Webwxgetheadimg struct {
	Seq      int    `json:"seq"`
	Username string `json:"username"`
	Skey     string `json:"skey"`
}

func WebwxgetheadimgNewConfig(webwxnewLoginPage *WebwxnewLoginPage, username string) *Webwxgetheadimg {
	return &Webwxgetheadimg{
		Seq:      0,
		Username: username,
		Skey:     webwxnewLoginPage.SKey,
	}
}

type Webwxgetvideo struct {
	MsgId string `json:"msgid"`
	Skey  string `json:"skey"`
}

func WebwxgetvideoNewConfig(webwxnewLoginPage *WebwxnewLoginPage, msgId string) *Webwxgetvideo {
	return &Webwxgetvideo{
		MsgId: msgId,
		Skey:  webwxnewLoginPage.SKey,
	}
}

type Webwxgetvoice struct {
	MsgId string `json:"msgid"`
	Skey  string `json:"skey"`
}

func WebwxgetvoiceNewConfig(webwxnewLoginPage *WebwxnewLoginPage, msgId string) *Webwxgetvoice {
	return &Webwxgetvoice{
		MsgId: msgId,
		Skey:  webwxnewLoginPage.SKey,
	}
}

type Webwxgetmedia struct {
	Sender          string `json:"sender"`
	Mediaid         string `json:"mediaid"`
	Encryfilename   string `json:"encryfilename"`
	Fromuser        int64  `json:"fromuser"`
	PassTicket      string `json:"pass_ticket"`
	WebwxDataTicket string `json:"webwx_data_ticket"`
}

func WebwxgetmediaNewConfig(webwxnewLoginPage *WebwxnewLoginPage, userData *UserData, cookies map[string]string, user MsgUser, filename string, mediaiId string) *Webwxgetmedia {

	return &Webwxgetmedia{
		Sender:          user.FromUserName,
		Mediaid:         mediaiId,
		Encryfilename:   filename,
		Fromuser:        userData.User.Uin,
		PassTicket:      webwxnewLoginPage.PassTicket,
		WebwxDataTicket: cookies["webwx_data_ticket"],
	}
}

type Webwxverifyuser struct {
	Get WebwxverifyuserGet

	Post WebwxverifyuserPost
}

type WebwxverifyuserGet struct {
	R int `json:"r"`
}

type WebwxverifyuserPost struct {
	BaseRequest        BaseRequest                 `json:"BaseRequest"`
	Opcode             int                         `json:"Opcode"`
	SceneList          []int                       `json:"SceneList"`
	SceneListCount     int                         `json:"SceneListCount"`
	VerifyContent      string                      `json:"VerifyContent"`
	VerifyUserList     []WebwxverifyuserVerifyUser `json:"VerifyUserList"`
	VerifyUserListSize int                         `json:"VerifyUserListSize"`
	Skey               string                      `json:"skey"`
}

type WebwxverifyuserVerifyUser struct {
	Value            string `json:"Value"`
	VerifyUserTicket string `json:"VerifyUserTicket"`
}

func WebwxverifyuserNewConfig(webwxnewLoginPage *WebwxnewLoginPage, verifyUserList []WebwxverifyuserVerifyUser) *Webwxverifyuser {
	var timestamp int64 = time.Now().UnixMilli()
	return &Webwxverifyuser{
		Get: WebwxverifyuserGet{R: int(timestamp)},
		Post: WebwxverifyuserPost{
			BaseRequest: BaseRequest{
				DeviceID: "e" + tools.StringRandom(10, 15),
				Sid:      webwxnewLoginPage.WxSid,
				Skey:     webwxnewLoginPage.SKey,
				Uin:      webwxnewLoginPage.WxUin,
			},
			Opcode:             3,
			SceneList:          []int{33},
			SceneListCount:     1,
			VerifyContent:      "",
			VerifyUserList:     verifyUserList,
			VerifyUserListSize: len(verifyUserList),
			Skey:               webwxnewLoginPage.SKey,
		},
	}
}
